﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Diagnostics;

namespace Lilium.Web.Mvc
{
	/// <summary>
	/// 
	/// </summary>
	/// <remarks>
	/// Thread Safety
	/// This type is thread safe.
	/// </remarks>
	public class ScriptResourceLibrary
	{
		public ScriptResourceLibrary(string name, IEnumerable<ScriptResource> resources)
		{
			if (string.IsNullOrEmpty(name))
				throw new ArgumentNullOrEmptyException("name");
			if (resources == null) throw new ArgumentNullException("resources");

			m_Name = name;
			m_ScriptResources = resources.ToDictionary(r => r.Name);

			GetScriptResource += (object sender, GetScriptResourceEventArgs e) =>
			{
				if (e.ScriptResource == null)
				{
					ScriptResource resource;
					ScriptResources.TryGetValue(e.ResourceName, out resource);
					e.ScriptResource = resource;
				}
			};
		}

		public void ProcessRequest(ControllerContext context)
		{
			var resourceName = context.RouteData.GetRequiredString("id");
			var args = new GetScriptResourceEventArgs(resourceName);
			OnGetScriptResource(args);
			if (args.ScriptResource != null)
				args.ScriptResource.ProcessRequest(context);
			else
				throw new InvalidOperationException(string.Format(
					Resources.Culture,
					Resources.ScriptResourceLibrary_ResourceNotFound_0resourceName_1libraryName,
					resourceName, Name));
		}

		#region public string Name

		private readonly string m_Name;

		public string Name { [DebuggerNonUserCodeAttribute] get { return m_Name; } }

		#endregion

		public event EventHandler<GetScriptResourceEventArgs> GetScriptResource;

		protected virtual void OnGetScriptResource(GetScriptResourceEventArgs e)
		{
			var handler = GetScriptResource;
			if (handler != null)
				handler(this, e);
		}

		#region private Dictionary<string, ScriptResource> ScriptResources

		private readonly Dictionary<string, ScriptResource> m_ScriptResources;

		private Dictionary<string, ScriptResource> ScriptResources { [DebuggerNonUserCodeAttribute] get { return m_ScriptResources; } }

		#endregion
	}
}